package ch.manage.movie.informationFetcher;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import ch.manage.movie.business.Movie;
import ch.manage.movie.gui.MovieList;

public class Fetcher extends AFetchMoviesFromIMDB {
	private URL url;
	private List<Movie> unfetchedMovies;
	private List<Movie> fetchedMovies;
	private List<Movie> unclearResultMovies;
	private MovieList movieListGui;
	static XStream xstream = new XStream(new DomDriver());
//
//	public List<Movie> getSpecificMovie(String movieName, int year) {
//		InputStream is = null;
//		movieName = movieName.replaceAll(" ", "%20");
//		Movie movie = new Movie();
//		try {
//			url = new URL("http://www.imdbapi.com/?t=" + movieName + "&y="
//					+ year + "&r=XML");
//			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//			DocumentBuilder db = dbf.newDocumentBuilder();
//			Document doc = db.parse(url.toString());
//			doc.getDocumentElement().normalize();
//			NodeList nodeList = doc.getElementsByTagName("movie");
//			if (nodeList.hashCode() == 0) {
//				return null;
//			}
//			Node movieNode = nodeList.item(0);
//
//			// Title
//
//			movie.setTitle(movieNode.getAttributes().item(11).getNodeValue());
//			// Release Date
//			DateFormat formatter = new SimpleDateFormat("dd MMM yyyy",
//					new Locale("en"));
//			String date = movieNode.getAttributes().item(9).getNodeValue();
//			Date releaseDate = (Date) formatter.parse(date);
//			movie.setRelease(releaseDate);
//			// Rated
//			movie.setRated(movieNode.getAttributes().item(8).getNodeValue());
//			// Duration
//			String duration = movieNode.getAttributes().item(10).getNodeValue();
//			int hours = 0, mins = 0;
//			if (duration.contains("h")) {
//				hours = Integer.parseInt(duration.substring(0,
//						duration.indexOf('h') - 1));
//			}
//			if (duration.contains("min")) {
//				mins = Integer.parseInt(duration.substring(
//						duration.indexOf('h') + 2, duration.indexOf('m') - 1));
//			}
//			movie.setDuration(hours * 60 + mins);
//			// Genre
//			movie.setGenre(Arrays.asList(movieNode.getAttributes().item(2)
//					.getNodeValue().split("[,]")));
//			// Directors
//			movie.setDirectors(Arrays.asList(movieNode.getAttributes().item(1)
//					.getNodeValue().split("[,]")));
//			// Writers
//			movie.setWriters(Arrays.asList(movieNode.getAttributes().item(12)
//					.getNodeValue().split("[,]")));
//			// Actors
//			movie.setActors(Arrays.asList(movieNode.getAttributes().item(0)
//					.getNodeValue().split("[,]")));
//			// Plot
//			movie.setDescription(movieNode.getAttributes().item(6)
//					.getNodeValue());
//			// Poster
//			String coverUrl = movieNode.getAttributes().item(7).getNodeValue();
//			String coverPath = "./covers/" + movie.getTitle() + ".jpg";
//			downloadImage(coverUrl, coverPath);
//			BufferedImage image = ImageIO.read(new URL(coverUrl));
//			movie.setCover(image);
//			movie.setCoverImagePath(coverPath);
//			// Rating
//			movie.setRating(Float.parseFloat(movieNode.getAttributes().item(4)
//					.getNodeValue()));
//			// Filepath
//			// IMDB Id
//			movie.setId(movieNode.getAttributes().item(3).getNodeValue());
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} finally {
//			if (is != null)
//				try {
//					is.close();
//				} catch (Exception e) {
//				}
//		}
//		return getFetchedMovies();
//
//	}
//
//
//	@Override
//	public void run() {
//		Movie tmpMovie;
//		for (Movie movie : unfetchedMovies) {
//			if (movie.getId() == null) {
//				// TODO read the release date correctly
//				System.out.println("Fetching "+movie.getTitle());
//				tmpMovie = this.getSpecificMovie(movie.getTitle(), 0);
//				if (tmpMovie != null) {
//					tmpMovie.setPath(movie.getPath());
//					fetchedMovies.add(tmpMovie);
//					movieListGui.updateMovieList(fetchedMovies);
//				}
//			}
//			System.out.println("Skipping "+movie.getTitle()+" "+movie.getId());
//		}
//	}

	public void setUnfetchedMovies(List<Movie> unfetchedMovies,
			MovieList movieListGui) {
		fetchedMovies = new ArrayList<Movie>();
		this.unfetchedMovies = unfetchedMovies;
		this.movieListGui = movieListGui;
	}

	public List<Movie> getFetchedMovies() {
		return fetchedMovies;
	}

	@Override
	public List<Movie> getMovies(List<Movie> unfetchedMovies) {
		List<Movie> result = new LinkedList<Movie>();
		final ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
		Set<Future<Movie>> allFutures = new HashSet<Future<Movie>>();

		for (Movie unfetchedMovie : unfetchedMovies) {
			allFutures.add(ex.submit(new FetchCallable(unfetchedMovie)));
		}
		for (Future<Movie> fetchedMovieFuture : allFutures) {
			try {
				Movie m = fetchedMovieFuture.get();
				result.add(m);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}
	
	private class FetchCallable implements Callable<Movie>{
		Movie movie;
		
		public FetchCallable(Movie movie){
			this.movie = movie;
		}
		
		@Override
		public Movie call() throws Exception {
			URL urll = new URL("http://www.imdb.com/xml/find?xml=1&nr=1&tt=on&q=Lord+Of+The+Rings");
			Object o = xstream.fromXML(urll);
			System.out.println(o.toString());
			System.out.println("huba");
			String imdbSearch = "http://www.imdb.com/find?q="+URLEncoder.encode(movie.getTitle(), "UTF-8");
			System.out.println(imdbSearch);
			URL imdbSearchURL = new URL(imdbSearch);
			URLConnection conn = imdbSearchURL.openConnection();
			conn.setRequestProperty("User-Agent", "ConCrawler/0.1 Mozilla/5.0");
			BufferedInputStream is = null;
			
			try {
				is = new BufferedInputStream(conn.getInputStream());
				Document doc = Jsoup.parse(is, null, imdbSearch);
				
//				Elements links = doc.select("a[href*=/title/]");
//				Elements links = doc.select("td > a[href*=/title/]");

				Elements mainDiv = doc.select("div#main").select("table");
				System.out.println(mainDiv.get(1));
				for (Element link : mainDiv) {
					String linkString = link.absUrl("href");
					if (linkString.startsWith("http")) {
//						result.add(linkString);
					}
				}
			} finally {
//				IOUtils.closeQuietly(is);
			}
			System.out.println("bb");
			return null;
		}
	}
	
	public static void main(String[] args){
		Fetcher fetcher = new Fetcher();
		List<Movie> movieList = new LinkedList<Movie>();
		Movie m = new Movie();
		m.setTitle("Fight Club");
		movieList.add(m);
		fetcher.getMovies(movieList);
	}
}
